namespace LccToolbox{


// VARS
template<class T>
bool VARS::form(T&& call){
	if(!typeCall.valid()) return false;// un ready

	auto itPair=insert(std::forward<T>(call));
	if(!itPair.second) return false;// already have or bad call
	
	// add new var
	itPair.first->Pag.alloc((*types_p)[typeCall].size);
	itPair.first->Pag.type()=(*types_p)[typeCall].type;
	return true;
}




// VARX
template<class T>
bool VARX::form(T&& type){
	if(!types_p) return false;

	auto it_here=find(CONST_LEFT_FORWARD(type));
	if(it_here!=end()) return true;// already formed
	auto it_there=types_p->find(LEFT_FORWARD(type));
	if(it_there==types_p->end()) return false;// un recorded in types
	auto itPair=insert(CONST_LEFT_FORWARD(type));
	if(!itPair.second) return false;// insert new type here fail
	
	// add new type
	itPair.first->Pag.types_p=types_p;
	itPair.first->Pag.typeCall=CONST_LEFT_FORWARD(type);
	types_p->enchant(itPair.first->Pag.typeCall);
	return true;
}








// MESS
template<class T>
int MESS::define( T&& note, size_t size){// -1 is already have, 0 is fail, 1 is success
	auto itPair=types.insert(LEFT_FORWARD(note));
	if(!itPair.second) return types.find(CONST_LEFT_FORWARD(note))==types.end()?0:-1;
	varx.form(CONST_LEFT_FORWARD(note));

	// {size_t map call}
	types[note].type=note.ID();
	types[note].size=size;
	return 1;
}


template<class T>
bool MESS::surround(T&&note){
	if(note==bindType)
	if(bindType.valid())
		return true;

	auto it=types.find(std::forward<T>(note));
	if(it==types.end()) return false;

	bindType=CONST_LEFT_FORWARD(*it);
	types.enchant(bindType);
	if(!binded) binded=true;
	return true;
}


// template<class T,class Tsub>
// bool MESS::appendMark( T&& note, size_t offset, Tsub&& subNote){
// 	if(!binded) return false;

// 	// {mark}
// }


template<class T>
bool MESS::appendFunc( T&& note, unifunc func){
	if(!binded) return false;// no record type

	auto itPair=types[bindType].func.insert(std::forward<T>(note));
	if(!itPair.second) return false;// insert fail

	itPair.first->Pag=func;
	return true;
}


template<class T>
bool MESS::instantiate(T&&note){
	if(!binded) return false;

	varx[bindType].form(std::forward<T>(note));
	return true;
}


template<class T>
char* MESS::var_address(T&& note){
	if(!binded) return nullptr;

	auto it=varx[bindType].find(std::forward<T>(note));
	if(it==varx[bindType].end()) return nullptr;// haven't record

	return it->Pag.ptr();
}



template<class Tfunc,class Tinstance>
char* MESS::call( Tfunc&& note_func, Tinstance&& note_instance, char* arg){
	if(!binded) return nullptr;

	auto it_func=types[bindType].func.find(std::forward<Tfunc>(note_func));
	if(it_func==types[bindType].func.end()) return nullptr;// no record func
	auto it_instance=varx[bindType].find(std::forward<Tinstance>(note_instance));
	if(it_instance==varx[bindType].end()) return nullptr;// no instance

	return it_func->Pag(it_instance->Pag.ptr(),arg);
}


// print(note);


}// namespace LccToolbox